//! @Author: DengLibin
//! @Date: Create in 2025-03-19 11:45:35
//! @Description:

use my_util_lib::{excel_util, http::HttpClient, pinyin};
use serde_json::json;
use sqlx::{MySql, Pool};

use crate::{
    component::web_driver::WebDriver,
    dao::mysql::{article_mysql_dao, mysql_dao},
    entity::article::Article,
    pojo::bo::EntitiesResultBo,
    sys::global::{to_global_result, GlobalResult},
};



/// @Author: DengLibin
/// @Date: Create in 2025-03-19 11:46:35
/// @Description: excel导入到数据库
pub async fn excel2db(
    xlsx_path: String,
    pool: &Pool<MySql>,
) -> Result<usize, Box<dyn std::error::Error>> {
    let articles = tokio::task::spawn_blocking(move || read_xlsx(xlsx_path)).await??;

    let size = articles.len();
    let _ = mysql_dao::insert_batch(&articles, pool).await?;

    Ok(size)
}

/// @Author: DengLibin
/// @Date: Create in 2025-03-19 11:58:29
/// @Description: 读取excel 转对象
pub fn read_xlsx(xlsx_path: String) -> GlobalResult<Vec<Article>> {
    to_global_result(do_read_xlsx(xlsx_path))
}
/// @Author: DengLibin
/// @Date: Create in 2025-03-19 12:11:07
/// @Description:
fn do_read_xlsx(xlsx_path: String) -> Result<Vec<Article>, Box<dyn std::error::Error>> {
    let mut articles: Vec<Article> = vec![];
    let excel = excel_util::read_xlsx(&xlsx_path)?;
    let mut id = 1;
    for sheet in excel.sheets.iter() {
        log::info!("{}", sheet.sheet_name);
        let mut headers: Vec<String> = vec![]; //表头
        for row in sheet.rows.iter() {
            if headers.is_empty() {
                for header in row.iter() {
                    //拼音作为字段名
                    let pinyin = pinyin::get_pinyin(&header);
                    headers.push(pinyin);
                }
            } else {
                //转对象
                let mut obj = serde_json::Map::new();

                for i in 0..row.len() {
                    let key = &headers[i];
                    let value = &row[i];
                    obj.insert(key.to_string(), json!(value));
                }
                obj.insert("id".to_string(), json!(id));
                obj.insert("content".to_string(), json!(""));
                id += 1;
                let json_str = serde_json::to_string(&obj)?;
                let article: Article = serde_json::from_str::<Article>(&json_str)?;

                articles.push(article);
            }
        }
    }

    Ok(articles)
}

/// @Author: DengLibin
/// @Date: Create in 2025-03-19 17:20:27
/// @param driver_url: web_driver 地址
/// @Description: 读取数据中url对应网页的内容并更新到数据库
pub async fn get_url_cotent(
    dirver_url: &str,
    pool: &Pool<MySql>,
) -> Result<(), Box<dyn std::error::Error>> {
    let dirver = WebDriver::new(dirver_url).await?;

    let mut datas = Vec::new();

    mysql_dao::scroll_all::<Article>(100, &pool, |mut rows| {
        datas.append(&mut rows);
        return true;
    })
    .await?;
    log::info!("数据量大小：{}", datas.len());
    process_rows(&datas, &dirver, pool).await;

    Result::Ok(())
}

/// @Author: DengLibin
/// @Date: Create in 2025-03-21 10:26:18
/// @Description: 提取内容机构实体
/// @param entities_extract_url  实体提取url
pub async fn extract_entites(
    entities_extract_url: &str,
    pool: &Pool<MySql>,
) -> Result<(), Box<dyn std::error::Error>> {
    let http_client = HttpClient::new();
    let datas = mysql_dao::get_all::<Article>(pool).await?;
    for data in datas.iter() {
        if data.content.is_empty() {
            continue;
        }
        let params = [("type", "ORG"), ("text", &data.content)];
        let entities_result =
            to_global_result(http_client.post_form(entities_extract_url, &params).await)?;
        let entites_bo = serde_json::from_str::<EntitiesResultBo>(&entities_result)?;
        if entites_bo.code == 0 {
            if entites_bo.data.is_empty() {
                continue;
            }
            let orgs = entites_bo.data.join(",");
            let r = article_mysql_dao::update_orgs(data.id, &orgs, pool).await;
            if let Result::Err(e) = r {
                log::error!("更新实体机构失败:{}, {}, {}", data.id, orgs, e);
            } else {
                log::info!("更新实体机构成功:{}", data.id);
            }
        } else {
            log::error!("获取实体信息失败:{}", entities_result);
        }
    }

    Result::Ok(())
}

 /// @Author: DengLibin
 /// @Date: Create in 2025-03-21 10:56:21
 /// @Description: 阜外医院分析 是否有夸大宣传
pub async fn analysis_fu_wai( pool: &Pool<MySql>,)-> Result<(), Box<dyn std::error::Error>>  {
    let datas = mysql_dao::get_all::<Article>(pool).await?;
    for data in datas.iter() {
        if let Some(orgs) = &data.orgs {
            orgs.split(",").for_each(|i|{
                if i.contains("阜外医院") {
                    println!("{}, {}, {}", data.id, i, data.yuanwenlianjie);
                }
            });
        }

    }

    Result::Ok(())
}




/// @Author: DengLibin
/// @Date: Create in 2025-03-19 17:47:38
/// @Description: 处理数据
async fn process_rows(rows: &Vec<Article>, web_driver: &WebDriver, pool: &Pool<MySql>) {
    for row in rows.iter() {
        if !row.content.is_empty() {
            continue;
        }
        let text_r = web_driver.get_text(&row.yuanwenlianjie).await;
        // 处理 text_r 的结果
        if let Result::Ok(text) = text_r {
            if !text.is_empty() {
                let r = article_mysql_dao::update_content(row.id, &text, pool).await;
                if let Result::Err(e) = r {
                    log::error!("更新内容失败:{}, {}", row.id, e);
                } else {
                    log::info!("更新内容成功:{}", row.id);
                }
            } else {
                log::warn!("获取网页内容为空:{}", row.yuanwenlianjie);
            }
        }
    }
}
